home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Interactive Reference Guide / C-C++ Interactive Reference Guide.iso / c_ref / csource5 / 318_01 / redbuf4.c < prev    next >
C/C++ Source or Header  |  1990-06-18  |  10KB  |  513 lines

  1. /*
  2.     RED buffer routines -- Full C version
  3.     Part 4 -- debugging routines.
  4.  
  5.     Source:  redbuf4.c
  6.     Version: December 3, 1984; January 18, 1990;
  7.  
  8.     Written by
  9.     
  10.         Edward K. Ream
  11.         166 N. Prospect
  12.         Madison WI 53705
  13.         (608) 257-0802
  14.  
  15.  
  16.     PUBLIC DOMAIN SOFTWARE
  17.  
  18.     This software is in the public domain.
  19.  
  20.     See red.h for a disclaimer of warranties and other information.
  21. */
  22. #include "red.h"
  23. #define PRINTER stdout
  24.  
  25. /*
  26.     Define output file for sherlock.
  27. */
  28. static FILE * sl_file = 0L;
  29.  
  30. /*
  31.     The XTRACE macro is used to eliminate traces when Sherlock
  32.     is not being used.
  33. */
  34. #undef XTRACE
  35.  
  36. #ifdef SHERLOCK
  37. #define XTRACE(a) a
  38. #else
  39. #define XTRACE(a)
  40. #define sl_cout(c)    putchar(c)
  41. #define sl_csout()    printf(", ");
  42. #define sl_iout(i)    printf("%d",i)
  43. #define sl_pout(p)    printf("%p",p)
  44. #define sl_sout(s)    printf("%s",s)
  45. #endif
  46.  
  47. /*
  48.     The observer effect:  None of the routines of this file
  49.     should ever call swap_in() because swap_in() causes
  50.     all kinds changes to the data structures which these
  51.     routines are trying to print out.
  52. */
  53.  
  54. /*
  55.     Dump global variables, all resident slots and
  56.     the current block.
  57. */
  58. void
  59. bufdump(void)
  60. {
  61.     SL_DISABLE();
  62.  
  63.     outxy(0,SCRNL1);
  64.     dump_vars();
  65.     dump_memory();
  66.     dump_block(b_bp);
  67.  
  68.     pmtzap();
  69.     pmtupd();
  70.     syscin();
  71.     pmtzap();
  72.     edclr();
  73.     edgo(bufln(), 0);
  74. }
  75.  
  76. /*
  77.     The following routine is used only if Sherlock is used.
  78.     It produces too much output to send to the screen.
  79. */
  80. #ifdef SHERLOCK 
  81.  
  82. void
  83. buftrace(void)
  84. {
  85.     struct BLOCK * bp;
  86.     int i;
  87.  
  88.     SL_DISABLE();
  89.  
  90.     sl_sout("\n\nbuftrace...\n");
  91.     trace_vars();
  92.     trace_memory();
  93.  
  94.     for (i = 0; i < DATA_RES; i++) {
  95.         bp = b_bpp[i];
  96.         if (bp != 0L) {
  97.             trace_block(b_bpp[i]);
  98.         }
  99.     }
  100. }
  101.  
  102. #endif /* SHERLOCK */
  103.  
  104. /*
  105.     System error routine.
  106. */
  107. void
  108. cant_happen(char *message)
  109. {
  110.     SL_DISABLE();
  111.  
  112.     pmtmess    (message, ":can't happen");
  113.     XTRACE(    sl_sout(message);
  114.         sl_sout(":cant_happen");
  115.         sl_cout('\n'));
  116.  
  117.     syscin();
  118.     syscin();
  119.  
  120.     XTRACE(buftrace());
  121.  
  122.     if (sl_file != 0L) {
  123.         fclose(sl_file);
  124.     }
  125.     exit(1);
  126. }
  127.  
  128. /*
  129.     Check the current block for consistency.
  130. */
  131. void
  132. check_block(char *message)
  133. {
  134.     int avail, i, nlines, total;
  135.  
  136.     SL_DISABLE();
  137.  
  138.     nlines = b_bp -> d_lines;
  139.     avail  = b1_avail();
  140.  
  141.     if (b_bp == (struct BLOCK *) ERROR ||
  142.         b_line < 0 || b_line > b_max_line + 1) {
  143.  
  144.         error("In check block 1.");
  145.         XTRACE(sl_sout("In check block 1\n"));
  146.         cant_happen(message);
  147.     }
  148.  
  149.     if ( nlines < 0 ||
  150.          nlines >= BUFF_SIZE ||
  151.          avail  < 0
  152.        ) {
  153.  
  154.         error("In Check block 2.");
  155.         XTRACE(sl_sout("In check block 2\n"));
  156.         cant_happen(message);
  157.     }
  158.  
  159.     /* Make sure there are at least enough lines. */
  160.     for (i = 0; i < nlines; i++) {
  161.         total = b1_tab(i);
  162.         if (total < 0 || total > BUFF_SIZE - avail) {
  163.  
  164.             error("In check block 3.");
  165.             XTRACE(sl_sout("In check block 3\n"));
  166.             cant_happen(message);
  167.         }
  168.     }
  169. }
  170.  
  171. /*
  172.     Dump the current block.
  173. */
  174. void
  175. dump_block(struct BLOCK *bp)
  176. {
  177.     char *buffer;
  178.     int  c, count, i, j, limit, nlines, offset;
  179.  
  180.     SL_DISABLE();
  181.  
  182.     XTRACE(    sl_sout("\n\ndump of block in slot ");
  183.         sl_iout(bp -> d_diskp); sl_sout("\n\n"));
  184.  
  185.     nlines = bp -> d_lines;
  186.     buffer = bp -> d_data;
  187.         offset = 0;
  188.     
  189.     for (i = 0; i < nlines; i++) {
  190.  
  191.         limit = b_tab(bp, i);
  192.         count = limit - offset;
  193.  
  194.         fprintf(PRINTER,
  195.         "line %3d, offset %3d, length %3d, total %3d:  ",
  196.         i + 1, offset, count, limit);
  197.  
  198.         XTRACE(    sl_sout("line ");    sl_iout(i+1);
  199.             sl_sout(", offset ");    sl_iout(offset);
  200.             sl_sout(", length ");    sl_iout(count);
  201.             sl_sout(", total ");    sl_iout(limit);
  202.             sl_sout(": "));
  203.  
  204.         if (count < 0) {
  205.             return;
  206.         }
  207.  
  208.         if (count >= 30) {
  209.             fprintf(PRINTER, "     \n");
  210.             XTRACE(sl_cout('\n'));
  211.         }
  212.         for (j = 0; j < count && j < 80; j++) {
  213.             c = buffer [offset + j] & 127;
  214.             if (c == '\t') {
  215.                 fprintf(PRINTER, " ");
  216.                 XTRACE(sl_sout(" "));
  217.             }
  218.             else if (c < 32) {
  219.                 fprintf(PRINTER,"^%c", c + 64);
  220.                 XTRACE(    sl_cout('^');
  221.                     sl_cout(c + 64));
  222.             }
  223.             else {
  224.                 fprintf(PRINTER, "%c", c);
  225.                 XTRACE(sl_cout(c));
  226.             }
  227.         }
  228.         fprintf(PRINTER, "     \n");
  229.         XTRACE(sl_cout('\n'));
  230.  
  231.         offset = limit;
  232.     }
  233. }
  234.  
  235. /*
  236.     Dump all the resident slots.
  237. */
  238. void
  239. dump_memory(void)
  240. {
  241.     struct BLOCK *bp;
  242.     int i;
  243.  
  244.     SL_DISABLE();
  245.  
  246.     XTRACE(sl_sout("\n\nfull dump of slots\n\n"));
  247.  
  248.     for (i = 0; i < DATA_RES; i++) {
  249.         bp = b_bpp [i];
  250.  
  251.         fprintf(PRINTER, "slot %2d, ", i);
  252.         XTRACE(sl_sout("slot "); sl_iout(i); sl_csout());
  253.  
  254.         fprintf(PRINTER,
  255.         "address %p, back %3d, diskp %3d, next %3d     \n",
  256.         bp, bp -> d_back, bp -> d_diskp, bp -> d_next);
  257.  
  258.         XTRACE(    sl_sout("address ");    sl_pout(bp);
  259.             sl_sout(", back ");    sl_iout(bp->d_back);
  260.             sl_sout(", diskp ");    sl_iout(bp->d_diskp);
  261.             sl_sout(", next ");    sl_iout(bp->d_next);
  262.             sl_cout('\n'));
  263.  
  264.         fprintf(PRINTER,
  265.         "lines %3d, lru %3d, status %3d, avail %3d     \n",
  266.         bp -> d_lines, bp -> d_lru,  bp -> d_status,
  267.         b_avail(bp));
  268.  
  269.         XTRACE(    sl_sout("lines ");    sl_iout(bp->d_lines);
  270.             sl_sout(", lru ");    sl_iout(bp->d_lru);
  271.             sl_sout(", status ");    sl_iout(bp->d_status);
  272.             sl_sout(", avail ");    sl_iout(b_avail(bp));
  273.             sl_cout('\n'));
  274.     }
  275. }
  276.  
  277. /*
  278.     Dump a brief description of the slots.
  279. */
  280. void
  281. dump_slots(void)
  282. {
  283.     struct BLOCK *bp1;
  284.     int i;
  285.  
  286.     SL_DISABLE();
  287.  
  288.     XTRACE(
  289.         for (i = 0; i < DATA_RES; i++) {
  290.             bp1 = b_bpp[i];
  291.             sl_iout(bp1->d_diskp);    sl_cout('(');
  292.             sl_iout(bp1->d_lru);
  293.             /* Limit of 10 per line. */
  294.             if ( (i%10) == 9) {
  295.                 sl_sout(")\n");
  296.             }
  297.             else {
  298.                 sl_sout("), ");
  299.             }
  300.         }
  301.     );
  302. }
  303.  
  304. /*
  305.     Dump all global variables.
  306. */
  307. void
  308. dump_vars(void)
  309. {
  310.     SL_DISABLE();
  311.  
  312.     XTRACE(sl_sout("\n\nDump of globals\n\n"));
  313.  
  314.     fprintf(PRINTER,
  315.     "start %d, line %d, maxline %d     \n",
  316.     b_start, b_line, b_max_line);
  317.  
  318.     XTRACE(    sl_sout("start ");    sl_iout(b_start);
  319.         sl_sout(", line ");    sl_iout(b_line);
  320.         sl_sout(", maxline ");    sl_iout(b_max_line);
  321.         sl_cout('\n'));
  322.  
  323.     fprintf(PRINTER,
  324.     "head %d, tail %d, free %d, max_diskp %d     \n",
  325.     b_head, b_tail, b_free, b_max_diskp);
  326.  
  327.     XTRACE(    sl_sout("head ");    sl_iout(b_head);
  328.         sl_sout(", tail ");    sl_iout(b_tail);
  329.         sl_sout(", free ");    sl_iout(b_free);
  330.         sl_sout(", max_diskp ");sl_iout(b_max_diskp);
  331.         sl_cout('\n'));
  332.  
  333.     fprintf(PRINTER,
  334.     "address %p, back %d, diskp %d, next %d, avail %d     \n",
  335.     b_bp, b_bp -> d_back,  b_bp -> d_diskp,
  336.     b_bp -> d_next, b1_avail());
  337.  
  338.     XTRACE(    sl_sout("address ");    sl_pout(b_bp);
  339.         sl_sout(", back ");    sl_iout(b_bp->d_back);
  340.         sl_sout(", diskp ");    sl_iout(b_bp->d_diskp);
  341.         sl_sout(", next ");    sl_iout(b_bp->d_next);
  342.         sl_sout(", avail ");    sl_iout(b1_avail());
  343.         sl_cout('\n'));
  344.  
  345.     fprintf(PRINTER,
  346.     "lines %d, lru %d, status %d     \n\n",
  347.     b_bp -> d_lines, b_bp -> d_lru,  b_bp -> d_status);
  348.  
  349.     XTRACE(    sl_sout("lines ");    sl_iout(b_bp->d_lines);
  350.         sl_sout(", lru ");    sl_iout(b_bp->d_lru);
  351.         sl_sout(", status ");    sl_iout(b_bp->d_status);
  352.         sl_cout('\n');        sl_cout('\n'));
  353. }
  354.  
  355. /*
  356.     All Sherlock output comes here.
  357.  
  358.     For those of you with Sherlock, comment out the version
  359.     of this routine in sherlock.c.
  360.  
  361.     The reason this routine is needed is so that Sherlock output
  362.     can be sent to a file instead of to stdout.
  363. */
  364. static int cout_inited = FALSE;
  365.  
  366. #ifdef SHERLOCK
  367.  
  368. void
  369. sl_cout(char c)
  370. {
  371.  
  372.     if (!cout_inited) {
  373.         cout_inited = TRUE;
  374.  
  375.         sl_file = sysfcreat("trace");
  376.         if (sl_file == 0L) {
  377.             disk_error("Can not create trace");
  378.         }
  379.     }
  380.  
  381.     /* Do not call sysfputc or we will get into an infinite recursion. */
  382.     if (sl_file != 0L) {
  383.         fputc(c, sl_file);
  384.     }
  385. }
  386.  
  387. #endif
  388.  
  389. /*
  390.     Same as dump_block, except to Sherlock output.
  391. */
  392. void
  393. trace_block(struct BLOCK *bp)
  394. {
  395.     char *buffer;
  396.     int  c, count, i, j, limit, nlines, offset;
  397.  
  398.     SL_DISABLE();
  399.  
  400.     XTRACE(    sl_sout("\n\ndump of disk block ");
  401.         sl_iout(bp -> d_diskp); sl_sout("\n\n"));
  402.  
  403.     nlines = bp -> d_lines;
  404.     buffer = bp -> d_data;
  405.         offset = 0;
  406.     
  407.     for (i = 0; i < nlines; i++) {
  408.  
  409.         limit = b_tab(bp, i);
  410.         count = limit - offset;
  411.  
  412.         XTRACE(    sl_sout("line ");    sl_iout(i+1);
  413.             sl_sout(", offset ");    sl_iout(offset);
  414.             sl_sout(", length ");    sl_iout(count);
  415.             sl_sout(", total ");    sl_iout(limit);
  416.             sl_sout(": "));
  417.  
  418.         if (count < 0) {
  419.             return;
  420.         }
  421.         for (j = 0; j < count && j < 80; j++) {
  422.             c = buffer [offset + j] & 127;
  423.             if (c == '\t') {
  424.                 XTRACE(sl_sout(" "));
  425.             }
  426.             else if (c < 32) {
  427.                 XTRACE(    sl_cout('^');
  428.                     sl_cout(c + 64));
  429.             }
  430.             else {
  431.                 XTRACE(sl_cout(c));
  432.             }
  433.         }
  434.         XTRACE(sl_cout('\n'));
  435.  
  436.         offset = limit;
  437.     }
  438. }
  439.  
  440. /*
  441.     Dump all the resident slots.
  442. */
  443. #ifdef SHERLOCK
  444.  
  445. void
  446. trace_memory(void)
  447. {
  448.     struct BLOCK *bp;
  449.     int i;
  450.  
  451.     SL_DISABLE();
  452.  
  453.     XTRACE(sl_sout("\n\nfull dump of slots\n\n"));
  454.  
  455.     for (i = 0; i < DATA_RES; i++) {
  456.         bp = b_bpp [i];
  457.  
  458.         XTRACE(sl_sout("slot "); sl_iout(i); sl_csout());
  459.  
  460.         XTRACE(    sl_sout("address ");    sl_pout(bp);
  461.             sl_sout(", back ");    sl_iout(bp->d_back);
  462.             sl_sout(", diskp ");    sl_iout(bp->d_diskp);
  463.             sl_sout(", next ");    sl_iout(bp->d_next);
  464.             sl_cout('\n'));
  465.  
  466.         XTRACE(    sl_sout("lines ");    sl_iout(bp->d_lines);
  467.             sl_sout(", lru ");    sl_iout(bp->d_lru);
  468.             sl_sout(", status ");    sl_iout(bp->d_status);
  469.             sl_sout(", avail ");    sl_iout(b_avail(bp));
  470.             sl_cout('\n'));
  471.     }
  472. }
  473.  
  474. #endif /* SHEROCK */
  475.  
  476. /*
  477.     Dump all global variables.
  478. */
  479. #ifdef SHERLOCK
  480.  
  481. void
  482. trace_vars(void)
  483. {
  484.     SL_DISABLE();
  485.  
  486.     XTRACE(sl_sout("\n\nDump of globals\n\n"));
  487.  
  488.     XTRACE(    sl_sout("start ");    sl_iout(b_start);
  489.         sl_sout(", line ");    sl_iout(b_line);
  490.         sl_sout(", maxline ");    sl_iout(b_max_line);
  491.         sl_cout('\n'));
  492.  
  493.     XTRACE(    sl_sout("head ");    sl_iout(b_head);
  494.         sl_sout(", tail ");    sl_iout(b_tail);
  495.         sl_sout(", free ");    sl_iout(b_free);
  496.         sl_sout(", max_diskp ");sl_iout(b_max_diskp);
  497.         sl_cout('\n'));
  498.  
  499.     XTRACE(    sl_sout("address ");    sl_pout(b_bp);
  500.         sl_sout(", back ");    sl_iout(b_bp->d_back);
  501.         sl_sout(", diskp ");    sl_iout(b_bp->d_diskp);
  502.         sl_sout(", next ");    sl_iout(b_bp->d_next);
  503.         sl_sout(", avail ");    sl_iout(b1_avail());
  504.         sl_cout('\n'));
  505.  
  506.     XTRACE(    sl_sout("lines ");    sl_iout(b_bp->d_lines);
  507.         sl_sout(", lru ");    sl_iout(b_bp->d_lru);
  508.         sl_sout(", status ");    sl_iout(b_bp->d_status);
  509.         sl_cout('\n');        sl_cout('\n'));
  510. }
  511.  
  512. #endif /* SHERLOCK */
  513.